package com.zenithmind.document.pojo.query;

import com.zenithmind.common.pojo.query.BaseQueryDTO;
import io.swagger.v3.oas.annotations.media.Schema;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.time.LocalDateTime;
import java.util.List;

/**
 * 文档访问日志查询DTO
 * 遵循单一职责原则：专注于访问日志查询条件
 * 遵循开闭原则：支持查询条件的扩展
 * 
 * @author ZenithMind Team
 * @since 2025-01-09
 */
@Data
@EqualsAndHashCode(callSuper = true)
@Schema(description = "文档访问日志查询DTO")
public class DocumentAccessLogQueryDTO extends BaseQueryDTO {

    @Schema(description = "文档ID", example = "doc123456")
    private String documentId;

    @Schema(description = "文档ID列表")
    private List<String> documentIds;

    @Schema(description = "用户ID", example = "user123456")
    private String userId;

    @Schema(description = "用户ID列表")
    private List<String> userIds;

    @Schema(description = "访问类型", example = "VIEW", allowableValues = {"VIEW", "DOWNLOAD", "SHARE", "EDIT", "DELETE"})
    private String accessType;

    @Schema(description = "访问类型列表")
    private List<String> accessTypes;

    @Schema(description = "IP地址", example = "192.168.1.100")
    private String ipAddress;

    @Schema(description = "IP地址列表")
    private List<String> ipAddresses;

    @Schema(description = "访问来源", example = "WEB", allowableValues = {"WEB", "MOBILE", "API", "DESKTOP"})
    private String accessSource;

    @Schema(description = "访问来源列表")
    private List<String> accessSources;

    @Schema(description = "设备类型", example = "PC", allowableValues = {"PC", "MOBILE", "TABLET", "OTHER"})
    private String deviceType;

    @Schema(description = "设备类型列表")
    private List<String> deviceTypes;

    @Schema(description = "浏览器类型", example = "Chrome")
    private String browserType;

    @Schema(description = "浏览器类型列表")
    private List<String> browserTypes;

    @Schema(description = "操作系统", example = "Windows 10")
    private String operatingSystem;

    @Schema(description = "操作系统列表")
    private List<String> operatingSystems;

    @Schema(description = "访问状态", example = "SUCCESS", allowableValues = {"SUCCESS", "FAILED", "TIMEOUT", "UNAUTHORIZED"})
    private String accessStatus;

    @Schema(description = "访问状态列表")
    private List<String> accessStatuses;

    @Schema(description = "网络类型", example = "WiFi", allowableValues = {"WiFi", "4G", "5G", "3G", "2G", "Ethernet", "Unknown"})
    private String networkType;

    @Schema(description = "网络类型列表")
    private List<String> networkTypes;

    @Schema(description = "地理位置", example = "北京市朝阳区")
    private String location;

    @Schema(description = "地理位置列表")
    private List<String> locations;

    @Schema(description = "会话ID", example = "session123456")
    private String sessionId;

    @Schema(description = "会话ID列表")
    private List<String> sessionIds;

    @Schema(description = "访问开始时间", example = "2025-01-09T00:00:00")
    private LocalDateTime accessTimeStart;

    @Schema(description = "访问结束时间", example = "2025-01-09T23:59:59")
    private LocalDateTime accessTimeEnd;

    @Schema(description = "最小访问时长（秒）", example = "10")
    private Long minAccessDuration;

    @Schema(description = "最大访问时长（秒）", example = "3600")
    private Long maxAccessDuration;

    @Schema(description = "最小停留时间（秒）", example = "5")
    private Long minStayDuration;

    @Schema(description = "最大停留时间（秒）", example = "1800")
    private Long maxStayDuration;

    @Schema(description = "最小响应时间（毫秒）", example = "100")
    private Long minResponseTime;

    @Schema(description = "最大响应时间（毫秒）", example = "5000")
    private Long maxResponseTime;

    @Schema(description = "最小数据传输量（字节）", example = "1024")
    private Long minDataTransferred;

    @Schema(description = "最大数据传输量（字节）", example = "10485760")
    private Long maxDataTransferred;

    @Schema(description = "错误代码", example = "404")
    private String errorCode;

    @Schema(description = "错误代码列表")
    private List<String> errorCodes;

    @Schema(description = "引用页面包含关键词", example = "search")
    private String referrerKeyword;

    @Schema(description = "访问路径包含关键词", example = "document")
    private String pathKeyword;

    @Schema(description = "用户代理包含关键词", example = "Chrome")
    private String userAgentKeyword;

    @Schema(description = "是否包含扩展属性", example = "true")
    private Boolean hasExtendedProperties;

    @Schema(description = "扩展属性关键词", example = "preview")
    private String extendedPropertiesKeyword;

    @Schema(description = "是否异常访问", example = "false")
    private Boolean isAbnormal;

    @Schema(description = "是否机器人访问", example = "false")
    private Boolean isBot;

    @Schema(description = "是否移动设备", example = "true")
    private Boolean isMobile;

    @Schema(description = "是否新用户", example = "false")
    private Boolean isNewUser;

    @Schema(description = "访问频次范围 - 最小值", example = "1")
    private Integer minAccessCount;

    @Schema(description = "访问频次范围 - 最大值", example = "100")
    private Integer maxAccessCount;

    @Schema(description = "经度范围 - 最小值", example = "116.0")
    private Double minLongitude;

    @Schema(description = "经度范围 - 最大值", example = "117.0")
    private Double maxLongitude;

    @Schema(description = "纬度范围 - 最小值", example = "39.0")
    private Double minLatitude;

    @Schema(description = "纬度范围 - 最大值", example = "40.0")
    private Double maxLatitude;

    @Schema(description = "屏幕分辨率", example = "1920x1080")
    private String screenResolution;

    @Schema(description = "屏幕分辨率列表")
    private List<String> screenResolutions;

    @Schema(description = "查询参数包含关键词", example = "page")
    private String queryParamsKeyword;

    @Schema(description = "备注包含关键词", example = "搜索")
    private String remarksKeyword;

    @Schema(description = "排序字段", example = "accessTime", allowableValues = {
            "accessTime", "accessDuration", "stayDuration", "responseTime", "dataTransferred"
    })
    private String sortField;

    @Schema(description = "排序方向", example = "DESC", allowableValues = {"ASC", "DESC"})
    private String sortDirection;

    @Schema(description = "分组字段", example = "accessType", allowableValues = {
            "accessType", "accessSource", "deviceType", "browserType", "operatingSystem", "location"
    })
    private String groupBy;

    @Schema(description = "统计类型", example = "COUNT", allowableValues = {"COUNT", "SUM", "AVG", "MAX", "MIN"})
    private String statisticsType;

    @Schema(description = "时间聚合粒度", example = "HOUR", allowableValues = {"MINUTE", "HOUR", "DAY", "WEEK", "MONTH"})
    private String timeGranularity;

    /**
     * 验证查询条件
     */
    public boolean isValid() {
        // 时间范围验证
        if (accessTimeStart != null && accessTimeEnd != null) {
            return !accessTimeStart.isAfter(accessTimeEnd);
        }
        
        // 数值范围验证
        if (minAccessDuration != null && maxAccessDuration != null) {
            return minAccessDuration <= maxAccessDuration;
        }
        
        if (minStayDuration != null && maxStayDuration != null) {
            return minStayDuration <= maxStayDuration;
        }
        
        if (minResponseTime != null && maxResponseTime != null) {
            return minResponseTime <= maxResponseTime;
        }
        
        if (minDataTransferred != null && maxDataTransferred != null) {
            return minDataTransferred <= maxDataTransferred;
        }
        
        if (minAccessCount != null && maxAccessCount != null) {
            return minAccessCount <= maxAccessCount;
        }
        
        // 地理位置范围验证
        if (minLongitude != null && maxLongitude != null) {
            return minLongitude <= maxLongitude;
        }
        
        if (minLatitude != null && maxLatitude != null) {
            return minLatitude <= maxLatitude;
        }
        
        return true;
    }

    /**
     * 是否有时间范围查询
     */
    public boolean hasTimeRange() {
        return accessTimeStart != null || accessTimeEnd != null;
    }

    /**
     * 是否有地理位置查询
     */
    public boolean hasLocationQuery() {
        return location != null || (minLongitude != null && maxLongitude != null && minLatitude != null && maxLatitude != null);
    }

    /**
     * 是否有性能指标查询
     */
    public boolean hasPerformanceQuery() {
        return minResponseTime != null || maxResponseTime != null || 
               minDataTransferred != null || maxDataTransferred != null ||
               minAccessDuration != null || maxAccessDuration != null ||
               minStayDuration != null || maxStayDuration != null;
    }

    /**
     * 获取默认排序
     */
    public String getDefaultSort() {
        return "accessTime DESC";
    }
}
